package com.ysf.cn.mainshi.test;

import com.ysf.cn.mainshi.mapper.IActor;
import com.ysf.cn.mainshi.pojo.Actor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK动态代理方式
 * @author ysf
 * @date 2020/2/23 11:24
 */
public class Client {

    public static void main(String[] args) {
        //一个剧组开始找演员
         Actor actor=new Actor();  //直接，没有代理的情况下
        /**
         * 代理:
         * 间接。
         * 获取代理对象：
         * 要求
         * 被代理类最少实现一个接口
         * 创建的方式
         * Proxy.newProxyInstance(三个参数)
         * 参数含义
         * ClassLoader:和被代理对象使用相同的类加载器。
         * Interfaces:和代理对象具有相同的行为。实现相同的接口。
         * InvocationHandler:如何代理。
         * 策略模式：使用场景是：
         * 数据有了，目的明确。
         * 如何达成目标，就是策略。
         */
        IActor proxyActory= (IActor) Proxy.newProxyInstance(
                actor.getClass().getClassLoader(),
                actor.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 执行被代理对象的任何方法，都会经过该方法。
                     * 此方法有拦截的功能。
                     * 参数
                     * @param proxy：代理对象的引用，不一定每次都用的到
                     * @param method：当前执行的方法对象
                     * @param args 执行方法所需要的参数
                     * @return  返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        String name=method.getName();
                        Float money=(Float)args[0];
                        Object rtValue=null;
                        if("basicAct".equals(name)){
                            //基本演出，没有2000不演出
                            if(money>2000){
                                //看上去剧组是给了8000，实际到演员手里只有4000
                                //这就是我们没有修改原来basicAct方法源码，对方法进行了增强
                                rtValue=method.invoke(actor,money/2);
                            }
                        }
                        if("dangerAct".equals(name)){
                            //危险演出，没有50000不演
                            if(money>5000){
                                //表面上剧组是给了50000，实际到演员手里只有25000
                                //这就是我们没有修改原来 dangerAct 方法源码，对方法进行了增强
                                rtValue=method.invoke(actor,money/2);
                            }
                        }
                        return rtValue;
                    }
                });
        //没有经纪公司的时候，剧组直接找演员。
//        actor.basicAct(1000f);
//        actor.dangerAct(5000f);
        //剧组找不到演员的时候，就联系经纪公司让经纪公司帮忙找演员
        proxyActory.basicAct(8000f);
        proxyActory.dangerAct(50000f);
    }
}
